package com.zhiche.wms.service.outbound.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.mapper.outbound.OutboundKeyPrepareLineMapper;
import com.zhiche.wms.domain.mapper.outbound.OutboundPrepareHeaderMapper;
import com.zhiche.wms.domain.mapper.outbound.OutboundPrepareLineMapper;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.outbound.OutboundKeyPrepareLine;
import com.zhiche.wms.domain.model.outbound.OutboundPrepareHeader;
import com.zhiche.wms.domain.model.outbound.OutboundPrepareLine;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.opbaas.paramdto.CommonConditionParamDTO;
import com.zhiche.wms.dto.outbound.OutboundPrepareDTO;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.outbound.IOutboundPrepareHeaderService;
import com.zhiche.wms.service.outbound.IOutboundPrepareLineService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.utils.CommonValueConstant;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 出库备料单明细 服务实现类
 * </p>
 *
 * @author zhaoguixin
 * @since 2018-06-27
 */
@Service
public class OutboundPrepareLineServiceImpl extends ServiceImpl<OutboundPrepareLineMapper, OutboundPrepareLine> implements IOutboundPrepareLineService {
    private final Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Autowired
    private IUserService userService;
    @Autowired
    private IOutboundPrepareHeaderService prepareHeaderService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private OutboundPrepareLineMapper outboundPrepareLineMapper;
    @Autowired
    private OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    private OutboundPrepareHeaderMapper outboundPrepareHeaderMapper;
    @Autowired
    private OutboundKeyPrepareLineMapper keyPrepareLineMapper;

    @Override
    public List<OutboundPrepareDTO> queryPageByLotId(String key, String houseid, Integer current, Integer size) {
        //if (StringUtils.isBlank(key)) {
        //    throw new BaseException("参数不能为空");
        //}
        if (StringUtils.isBlank(houseid)) {
            throw new BaseException("仓库id不能为空");
        }
        if (StringUtils.isNotBlank(key)) {
            EntityWrapper<OtmOrderRelease> oorEW = new EntityWrapper<>();
            oorEW.eq("qr_code", key)
                    .ne("status", TableStatusEnum.STATUS_50.getCode())
                    .orderBy("id", false);
            OtmOrderRelease release = releaseService.selectOne(oorEW);
            if (release != null) {
                key = release.getVin();
            }
        }
        Page<OutboundPrepareDTO> page = new Page<>(current, size);
        EntityWrapper<OutboundPrepareDTO> ew = new EntityWrapper<>();
        ew.eq("store_house_id", houseid)
                .ne("status", TableStatusEnum.STATUS_50.getCode());
        if (StringUtils.isNotBlank(key)) {
            ew.andNew()
                    .like("owner_order_no", key)
                    .or()
                    .like("lot_No1", key)
                    .or()
                    .eq("qr_code", key);
        }
        ew.orderBy("id", false);
        return baseMapper.queryPage(page, ew);
    }

    @Override
    public OutboundPrepareDTO getPrepare(String key, Long houseId) {
        try {
            if (StringUtils.isBlank(key)) {
                throw new BaseException("参数不能为空");
            }
            return baseMapper.getPrepare(new Long(key), houseId);
        } catch (NumberFormatException e) {
            LOGGER.error(e.toString());
            throw new BaseException("key非数字");
        } catch (Exception e) {
            LOGGER.error(e.toString());
            throw new BaseException("获取备料信息出错");
        }
    }

    @Override
    public OutboundPrepareDTO getPrepareBykey(String key, Long houseId) {
        try {
            if (StringUtils.isBlank(key)) {
                throw new BaseException("扫码信息不能为空");
            }
            EntityWrapper<OtmOrderRelease> oorEW = new EntityWrapper<>();
            oorEW.eq("qr_code", key)
                    .ne("status", TableStatusEnum.STATUS_50.getCode())
                    .orderBy("id", false);
            OtmOrderRelease release = releaseService.selectOne(oorEW);
            if (release != null) {
                key = release.getVin();
            }
            return baseMapper.getPrepareBykey(key, houseId);
        } catch (Exception e) {
            LOGGER.error(e.toString());
            throw new BaseException("获取备料信息出错");
        }
    }

    @Override
    public OutboundPrepareDTO updateStatus(String key, Long houseId) {
        try {
            if (Strings.isNullOrEmpty(key)) throw new BaseException("id号为空");
            OutboundPrepareLine line = this.selectById(Long.valueOf(key));
            if (line == null) {
                throw new BaseException("该备料明细已删除");
            }
            if (TableStatusEnum.STATUS_50.getCode().equals(line.getStatus())) {
                throw new BaseException("该备料明细已取消");
            }
            User user = userService.getLoginUser();
            OutboundPrepareLine upLine = new OutboundPrepareLine();
            upLine.setId(line.getId());
            upLine.setStatus(TableStatusEnum.STATUS_20.getCode());
            upLine.setGmtModified(new Date());
            upLine.setStartTime(new Date());
            upLine.setUserModified(user.getName());
            if (user != null) {
                upLine.setPreparetor(user.getName());
            }
            baseMapper.updateById(upLine);
            //更新头开始
            EntityWrapper<OutboundPrepareHeader> headerEW = new EntityWrapper<>();
            headerEW.eq("id", line.getHeaderId())
                    .ne("status", TableStatusEnum.STATUS_50.getCode());
            OutboundPrepareHeader header = new OutboundPrepareHeader();
            header.setStartTime(new Date());
            //header.setStatus(TableStatusEnum.STATUS_20.getCode());
            header.setStatus(TableStatusEnum.STATUS_30.getCode());
            header.setUserModified(user.getName());
            prepareHeaderService.update(header, headerEW);
            return this.getPrepare(key, houseId);
        } catch (Exception e) {
            LOGGER.error(e.toString());
            throw new BaseException("修改备料信息出错");
        }
    }

    @Override
    public List<Map<String, String>> realVehicleCheck(CommonConditionParamDTO conditions) {
        List<Map<String, String>> resultList = new ArrayList<>();
        //1、入参校验
        Map<String, String> condition = checkRealVehicleParams(conditions);

        //2、登录校验
        String userName = this.getLoginUserName();

        //3、车架号是否相同
        String[] keyVins = condition.get("keyVins").split(";");
        String[] headerIds = condition.get("lineIds").split(";");
        if(keyVins.length != headerIds.length){
            throw new BaseException(99,"车架号和id不匹配，请重新确认！");
        }
        for (int i = 0; i < keyVins.length && i < headerIds.length; i++) {
            String keyVin = keyVins[i];
            String headerId = headerIds[i];
            Map<String, String> resultMap = new HashMap<>();
            Wrapper<OutboundPrepareLine> ew = new EntityWrapper<>();
            ew.eq("id", headerId);
            ew.eq("lot_no1", keyVin);
            List<OutboundPrepareLine> outboundPrepareLine = outboundPrepareLineMapper.selectList(ew);
            if (CollectionUtils.isEmpty(outboundPrepareLine)) {
                //运单查询车架号
                resultMap = this.queryVinByQrCode(userName, headerId, keyVin);
            } else {
                resultMap.put("keyVin", keyVin);
                resultMap.put("checkStatue", CommonValueConstant.VEHICLE_CHECKOUT_STATUS_1);
                this.updatePrepareStatus(keyVin, userName, headerId, CommonValueConstant.VEHICLE_CHECKOUT_STATUS_1);
            }
            resultList.add(resultMap);
        }
        return resultList;
    }

    @Override
    public void batchUpdateStatus (String id) {
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        //备料头表
        OutboundPrepareHeader outboundPrepareHeader = new OutboundPrepareHeader();
        outboundPrepareHeader.setStatus(CommonValueConstant.OUTBOUND_HEADER_STATUS_30);
        outboundPrepareHeader.setUserModified(loginUser.getName());
        outboundPrepareHeader.setGmtModified(new Date());
        Wrapper<OutboundPrepareHeader> headerEw = new EntityWrapper<>();
        headerEw.eq("id", id);
        outboundPrepareHeaderMapper.update(outboundPrepareHeader, headerEw);
        //备料头详细表
        OutboundPrepareLine outboundPrepareLineParam = new OutboundPrepareLine();
        outboundPrepareLineParam.setStatus(CommonValueConstant.OUTBOUND_STATUS_20);
        outboundPrepareLineParam.setUserModified(loginUser.getName());
        outboundPrepareLineParam.setStartTime(new Date());
        outboundPrepareLineParam.setGmtModified(new Date());
        if(StringUtils.isNotEmpty(loginUser.getName())){
            outboundPrepareLineParam.setPreparetor(loginUser.getName());
        }
        Wrapper<OutboundPrepareLine> lineEw = new EntityWrapper<>();
        lineEw.eq("header_id", id);
        lineEw.eq("status", CommonValueConstant.OUTBOUND_STATUS_10);
        outboundPrepareLineMapper.update(outboundPrepareLineParam, lineEw);
    }

    @Override
    public List<OutboundPrepareDTO> getVehicleDetail(CommonConditionParamDTO dto) {
        LOGGER.info("OutboundPrepareHeaderServiceImpl.getVehicleDetail param:{}", JSONObject.toJSONString(dto));
        if (dto == null) {
            throw new BaseException("参数不能为空");
        }
        Map<String, String> con = dto.getCondition();
        if (con == null || con.isEmpty()) {
            throw new BaseException("condition不能为空");
        }
        String headerId = con.get("preHeaderId");
        if (StringUtils.isBlank(headerId)) {
            throw new BaseException("备料头id不能为空");
        }
        Wrapper<OutboundPrepareDTO> lineEW = new EntityWrapper<>();
        lineEW.eq("a.header_id", headerId)
                .ne("a.status",TableStatusEnum.STATUS_40.getCode())
                .orderBy("a.id",false);
        return baseMapper.selectLinesWithHouse(lineEW);
    }

    /**
     * 获取登录用户名
     *
     * @return 用户名
     */
    private String getLoginUserName() {
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空");
        }
        return loginUser.getName();
    }

    /**
     * 查询车架号
     *
     * @param userName 登录用户
     * @param headerId 备料单头
     * @param keyVin   车架号
     */
    private Map<String, String> queryVinByQrCode(String userName, String headerId, String keyVin) {
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("keyVin", keyVin);

        //1、根据绑定的二维码编号获取otm_order_release车架号
        Wrapper<OtmOrderRelease> ew = new EntityWrapper<>();
        ew.eq("qr_code", keyVin);
        ew.orderBy("gmt_create", false);
        List<OtmOrderRelease> otmOrderRelease = otmOrderReleaseMapper.selectList(ew);
        String status = CommonValueConstant.VEHICLE_CHECKOUT_STATUS_2;
        if (!CollectionUtils.isEmpty(otmOrderRelease)) {
            //2、获取到车架号和备料详情里面的车架号比对
            Wrapper<OutboundPrepareLine> obpew = new EntityWrapper<>();
            obpew.eq("id", headerId);
            obpew.eq("lot_no1", otmOrderRelease.get(0).getVin());
            List<OutboundPrepareLine> outboundPrepareLine = outboundPrepareLineMapper.selectList(obpew);
            if (!CollectionUtils.isEmpty(outboundPrepareLine)) {
                //resultMap.put("keyVin", otmOrderRelease.get(0).getVin());
                status = CommonValueConstant.VEHICLE_CHECKOUT_STATUS_1;
                this.updatePrepareStatus(otmOrderRelease.get(0).getVin(), userName, headerId, status);
            }
        }
        resultMap.put("checkStatue", status);
        return resultMap;
    }

    /**
     * 更新备料状态
     *
     * @param keyVin      车架号
     * @param userName    登录用户
     * @param headerId    备料单头键
     * @param checkStatus 状态
     */
    private void updatePrepareStatus(String keyVin, String userName, String headerId, String checkStatus) {
        OutboundPrepareLine outboundPrepareLineParam = new OutboundPrepareLine();
        outboundPrepareLineParam.setUserModified(userName);
        outboundPrepareLineParam.setVehicleCheckoutStatus(checkStatus);
        if (CommonValueConstant.VEHICLE_CHECKOUT_STATUS_2.equals(checkStatus)) {
            outboundPrepareLineParam.setRemarks("车架号不匹配");
        }
        Wrapper<OutboundPrepareLine> ew = new EntityWrapper<>();
        ew.eq("lot_no1", keyVin);
        ew.eq("id", headerId);
        outboundPrepareLineMapper.update(outboundPrepareLineParam, ew);
        //修改钥匙的状态
        this.updateKeyPrepareStatus(headerId,userName);
    }

    private void updateKeyPrepareStatus (String headerId, String userName) {
        OutboundPrepareLine param = new OutboundPrepareLine();
        param.setId(Long.valueOf(headerId));
        OutboundPrepareLine outboundPrepareLine = outboundPrepareLineMapper.selectOne(param);
        if (null != outboundPrepareLine) {
            OutboundKeyPrepareLine keyPrepareLine = new OutboundKeyPrepareLine();
            keyPrepareLine.setUserModified(userName);
            keyPrepareLine.setStatus(String.valueOf(TableStatusEnum.STATUS_30.getCode()));
            keyPrepareLine.setVehicleCheckoutStatus(String.valueOf(TableStatusEnum.STATUS_1.getCode()));
            Wrapper<OutboundKeyPrepareLine> keyEw = new EntityWrapper<>();
            keyEw.eq("notice_line_id", outboundPrepareLine.getNoticeLineId());
            keyEw.eq("lot_no1", outboundPrepareLine.getLotNo1());
            keyEw.eq("status", TableStatusEnum.STATUS_20.getCode());
            keyPrepareLineMapper.update(keyPrepareLine, keyEw);
        }
    }

    /**
     * 实车校验入参为空判断
     *
     * @param conditions
     * @return
     */
    private Map<String, String> checkRealVehicleParams(CommonConditionParamDTO conditions) {
        Map<String, String> condition = conditions.getCondition();
        if (Objects.isNull(condition)) {
            throw new BaseException(99, "参数为空");
        }
        if (StringUtils.isEmpty(condition.get("keyVins"))) {
            throw new BaseException(99, "参数【keyVins】为空");
        }
        if (StringUtils.isEmpty(condition.get("lineIds"))) {
            throw new BaseException(99, "参数【lineIds】为空");
        }
        return condition;
    }
}
